using System;
using System.Web.Caching;
using EPiServer.Common.Cache;

namespace EPiAbstractions.Common.Cache
{
    public class CacheHandlerFacade : ICacheHandlerFacade
    {
        private static CacheHandlerFacade _instance;

        public CacheHandlerFacade()
        {
            CacheHandler.RemovedCache += OnRemovedCache;
        }

        public static CacheHandlerFacade Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new CacheHandlerFacade();

                return _instance;
            }

            set { _instance = value; }
        }

        #region ICacheHandlerFacade Members

        public event CacheHandler.RemoveCacheEventHandler RemovedCache;

        public virtual void InitializeCache()
        {
            CacheHandler.InitializeCache();
        }

        public virtual Object GetCachedObject(Delegate cacheObjectGetter, Object[] getterArgs, String[] key)
        {
            return CacheHandler.GetCachedObject(cacheObjectGetter, getterArgs, key);
        }

        public virtual Object GetCachedObject(Delegate cacheObjectGetter, Object[] getterArgs, TimeSpan? cacheTimeSpan, String[] key)
        {
            return CacheHandler.GetCachedObject(cacheObjectGetter, getterArgs, cacheTimeSpan, key);
        }

        public virtual Object GetCachedObject(Delegate cacheObjectGetter, Object[] getterArgs, TimeSpan? cacheTimeSpan,
                                              NotFoundInCacheAnnouncer notFoundInCacheAnnouncer, String[] key)
        {
            return CacheHandler.GetCachedObject(cacheObjectGetter, getterArgs, cacheTimeSpan, notFoundInCacheAnnouncer, key);
        }

        public virtual Object GetCachedObject(String[] key)
        {
            return CacheHandler.GetCachedObject(key);
        }

        public virtual Object GetCachedObject(String keyPath)
        {
            return CacheHandler.GetCachedObject(keyPath);
        }

        public virtual void SetCachedObject(ICacheable cacheable)
        {
            CacheHandler.SetCachedObject(cacheable);
        }

        public virtual void SetCachedObject(Object obj, String[] key)
        {
            CacheHandler.SetCachedObject(obj, key);
        }

        public virtual void SetCachedObject(Object obj, Int32 seconds, String[] key)
        {
            CacheHandler.SetCachedObject(obj, seconds, key);
        }

        public virtual void SetCachedObject(Object obj, DateTime expiry, String[] key)
        {
            CacheHandler.SetCachedObject(obj, expiry, key);
        }

        public virtual void SetCachedObject(Object obj, TimeSpan span, CacheItemPriority priority, String[] key)
        {
            CacheHandler.SetCachedObject(obj, span, priority, key);
        }

        public virtual void SetCachedObject(Object obj, DateTime expiry, CacheItemPriority priority, String[] key)
        {
            CacheHandler.SetCachedObject(obj, expiry, priority, key);
        }

        public virtual void RemoveCachedObject(ICacheable cacheable)
        {
            CacheHandler.RemoveCachedObject(cacheable);
        }

        public virtual void RemoveCachedObject(String[] key)
        {
            CacheHandler.RemoveCachedObject(key);
        }

        public virtual void RemoveCachedObject(String keyPath)
        {
            CacheHandler.RemoveCachedObject(keyPath);
        }

        public virtual void AddDependency(String[] dependsOn, String[] dependent)
        {
            CacheHandler.AddDependency(dependsOn, dependent);
        }

        public virtual void RemoveDependency(String[] dependsOn, String[] dependent)
        {
            CacheHandler.RemoveDependency(dependsOn, dependent);
        }

        public virtual void OnRemoveCache(String key, Object val, CacheItemRemovedReason reason)
        {
            CacheHandler.OnRemoveCache(key, val, reason);
        }

        public virtual String GenerateCacheKey(String[] keyParts)
        {
            return CacheHandler.GenerateCacheKey(keyParts);
        }

        public virtual String[] ParseCacheKey(String key)
        {
            return CacheHandler.ParseCacheKey(key);
        }

        #endregion

        public virtual void OnRemovedCache(String key, Object val, CacheItemRemovedReason reason)
        {
            if (RemovedCache != null)
                RemovedCache(key, val, reason);
        }
    }
}